/*
 * @Author: hongbin
 * @Date: 2023-10-01 09:19:11
 * @LastEditors: hongbin
 * @LastEditTime: 2023-10-06 11:28:02
 * @Description: 
 */
import { LoadGLTF, MethodBaseSceneSet, EveryFrame } from "../../ThreeHelper/decorators/index";
import * as THREE from "three";

export class Main {

    constructor(helper) {
        this.helper = helper;
        this.init()
    }

    @MethodBaseSceneSet({
        addAxis: false,
        cameraPosition: new THREE.Vector3(0, 0, 3),
    })
    init() {
        this.load()
        const box = new THREE.Mesh(new THREE.BoxGeometry(3, 3, 3, 20, 20, 20), new THREE.ShaderMaterial({
            side: THREE.DoubleSide,
            vertexShader: `
            varying vec2 vUv;
            varying vec3 vColor;
            
            void main() {
                vUv = uv-0.05;
                vec4 modelViewPosition = modelViewMatrix * vec4(position, 1.0);
                vColor = vec3(position.x);
                gl_Position = projectionMatrix * modelViewPosition;
            }`,
            fragmentShader: `
            varying vec2 vUv;
            varying vec3 vColor;
            
            void main() {
                float sx =float(fract(6. * vUv.x) > 0.5);	
                float sy =float(fract(6. * vUv.y) > 0.5);	
                if(sx*sy == 0.0) discard;
                vec3 color = vec3(sx * sy);
                gl_FragColor = vec4(color, 1.0);
            }`
        }))
        // this.helper.add(box);
    }

    @EveryFrame
    animation() {
        this.skeletonAnimation.update()
    }

    @LoadGLTF('../../static/dance.glb')
    load(gltf) {
        this.skeletonAnimation = new this.helper.SkeletonAnimation()
        this.skeletonAnimation.init(
            gltf.scene,
            gltf.animations
        )
        this.animation()
        this.pointMaterial(gltf.scene)
        this.helper.add(gltf.scene)
    }

    pointMaterial(obj) {
        const Ch44 = obj.getObjectByName('Ch44');
        Ch44.material.side = THREE.FrontSide;

        const uniforms = {
            uSize: { value: 100 },
            uSpace: { value: 0.5 },
            uProgress: { value: 0. },
        }
        {
            this.helper.gui.add(uniforms.uSize, 'value', 1, 168).name('数量')
            this.helper.gui.add(uniforms.uProgress, 'value', -1, 1).name('进度')
            this.helper.gui.add(uniforms.uSpace, 'value', 0, 1).step(0.01).name('间隙')
            this.helper.gui.add(Ch44.material, 'metalness', 0, 1).step(0.01).name('金属度')
            this.helper.gui.add(Ch44.material, 'roughness', 0, 1).step(0.01).name('粗糙度')

            this.helper.gui.add({ v: 0 }, 'v', 0, 1).name('数量间隙相对调整').onChange((v) => {
                uniforms.uSize.value = v * 168;
                uniforms.uSpace.value = 1 - v;
            })
            this.helper.gui.add({ v: 0 }, 'v', 0, 1).name('数量间隙反向调整').onChange((v) => {
                uniforms.uSize.value = Math.max(1, (1 - v) * 168);
                uniforms.uSpace.value = 1 - v;
                uniforms.uProgress.value = Math.max(0, 1 - v * 4);
            })
            this.helper.gui.add({ v: 0 }, 'v', 0, 1).name('数量间隙反向调整').onChange((v) => {
                uniforms.uSize.value = (1 - v) * 168;
                uniforms.uSpace.value = v;
            })
        }
        this.helper.gui.add({ DoubleSide: false }, 'DoubleSide').onChange((s) => {
            if (s) Ch44.material.side = THREE.DoubleSide;
            else Ch44.material.side = THREE.FrontSide;
        }).name('显示正反两面')

        Ch44.material.onBeforeCompile = (shader) => {
            // console.log(shader.vertexShader)
            // console.log(shader.fragmentShader)
            Object.assign(shader.uniforms, uniforms)
            shader.vertexShader = shader.vertexShader.replace('#include <common>',
                `
                #include <common>
                varying vec2 vUv;
                uniform float uProgress;
            `
            )
            shader.vertexShader = shader.vertexShader.replace('#include <uv_vertex>',
                `
                #include <uv_vertex>
                vUv = uv;
            `
            )
            shader.vertexShader = shader.vertexShader.replace('#include <begin_vertex>',
                `
                #include <begin_vertex>
                transformed.x += sin(uProgress);
                transformed.y += sin(uProgress);
                transformed.z += sin(uProgress);
            `
            )
            shader.fragmentShader = shader.fragmentShader.replace('#include <common>',
                `
                #include <common>
                varying vec2 vUv;
                uniform float uSize;
                uniform float uSpace;
            `
            )
            shader.fragmentShader = shader.fragmentShader.replace('#include <dithering_fragment>',
                `
                #include <dithering_fragment>
                float sx =float(fract(uSize * vUv.x) > uSpace);	
                float sy =float(fract(uSize * vUv.y) > uSpace);	
                if(sx*sy == 0.0) discard;
            `
            )
        };
    }
}